/**
 * 代理模式
 */

// proxy 用于修改某些操作的默认行为，等同于语言层面做出修改，所以属于 元编程

var obj = new Proxy({}, {
    get: function(target, propKey, receiver) {
        console.log(`getting ${propKey}`)
        return Reflect.get(target, propKey, receiver)
    },
    set:function(target, propKey, value, receiver) {
        console.log(`setting ${propKey}`)
        return Reflect.set(target, propKey, value, receiver)
    }
})
obj.count = 1;
++obj.count;

var proxy = new Proxy({}, {
    get: function(target, propKey) {
        return 35;
    }
})

console.log(proxy.time)
console.log(proxy.name)
console.log(proxy.title)

// proxy实例可以作为其他对象的原型对象
let obj1 = Object.create(proxy)
console.log(obj1.time)

var object = {proxy: new Proxy({}, {})};

// 同一个拦截器，可以设置拦截多个操作
var handle = {
    get(target, name) {
        if (name === 'prototype') {
            return Object.prototype
        }
        return 'hello' + name
    },
    apply(target, thisBinding, args){
        console.log('apply')
        return args[0]
    },
    construct(target, args){
        return {value: args[1]}
    }
}

var fproxy = new Proxy(function(x,y) {
    return x + y
}, handle);
console.log(fproxy(1, 2))
console.log(new fproxy(1,2))
console.log(fproxy.prototype === Object.prototype)


// get
var person = {
    name: '张三'
}
var proxy = new Proxy(person, {
    get(target, propKey) {
        if (propKey in target) {
            return target[propKey]
        }else {
            throw new ReferenceError(`prop name:${propKey} does not exist`)
        }
    }
})
proxy.name
// proxy.age

// get 方法可以继承
let proto = new Proxy({}, {
    get(target, propKey, receiver){
        console.log('GET'+propKey)
        return target[propKey]
    }
})
let obj2 = Object.create(proto);
obj2.foo

// 使用get拦截，实现数组实现负数的索引
function createArray(...args) {
    return new Proxy([...args], {
        get(target, propKey, receiver){
            let index = Number(propKey);
            if (index < 0) {
                propKey = String(target.length + index)
            }
            return Reflect.get(target, propKey, receiver)
        }
    })
}
var arr = createArray('a', 'b', 'c')
console.log(arr[-1])

// “婚介所”实现
// 规定礼物的数据结构
const present = {
    type: '巧克力',
    value: 60
}
// 美女
const girl = {
    name: '小美',
    aboutMe: '...',
    age: 24,
    career:'',
    fakeAvatar: '',
    avatar: '',
    phone: 1234,
    presents: '',
    bottomValue: 50,
    lastPresent: parent
}

// 普通私密信息
const baseInfo = ['age', 'career'];
//最私密信息
const privateInfo = ['avatar', 'phone'];

// 用户对象实例
const user = {
    isValidated: true,//实名
    isVIP: false, // vip
}

// 婚介所
const JuejinLovers = new Proxy(girl, {
    get: function(girl, key) {
        if (baseInfo.includes(key) && !user.isValidated) {
            alert('您还没完成验证')
            return;
        }
        if (user.isValidated && privateInfo.includes(key) && !user.isVIP) {
            alert('只有VIP才可以查看该信息')
            return;
        }
    },
    set: function(girl, key, val) {
        if (key ==='lastPresent') {
            if (val.value < girl.bottomValue) {
                alert('sorry，您的礼物被拒收')
                return
            }
            girl[key] = val;
            girl.parent = [...girl.parents, val]
        }
    }
})